package com.share.finance.fund.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.share.common.common.Page;
import com.share.common.utils.DateUtil;
import com.share.common.utils.RateUtil;
import com.share.finance.fund.mapper.RepaymentPlanMapper;
import com.share.finance.fund.model.db.RepaymentPlan;
import com.share.finance.fund.model.db.RepaymentRecord;
import com.share.finance.fund.model.vo.RepaymentPlanPageReq;
import com.share.finance.fund.service.ILoanInfoService;
import com.share.finance.fund.service.IRepaymentPlanService;
import com.share.finance.fund.service.IRepaymentRecordService;
import com.share.finance.risk.common.enums.OverdueStatusEnum;
import com.share.finance.risk.common.enums.RepayPlanEnum;
import com.share.finance.risk.common.enums.RepayStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * <p>
 * 还款计划  服务实现类
 * </p>
 *
 * @author author
 * @since 2024-08-27
 */
@Slf4j
@Service
public class RepaymentPlanServiceImpl extends ServiceImpl<RepaymentPlanMapper, RepaymentPlan> implements IRepaymentPlanService {

    @Resource
    private RepaymentPlanMapper repaymentRlanMapper;

    @Autowired
    private ILoanInfoService loanInfoService;

    @Autowired
    private IRepaymentRecordService iRepaymentRecordService;

    // 模拟 生成还款记录 并更新 还款计划
    @Override
    public int genRepayRecord() {
        int re = 0;
        LambdaQueryWrapper<RepaymentPlan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RepaymentPlan::getRepayStatus, RepayPlanEnum.UN_PAY.value);
        queryWrapper.between(RepaymentPlan::getBillTime, DateUtil.getMonthBegin(), DateUtil.getMonthEnd());
        queryWrapper.last("limit 9");
        List<RepaymentPlan> list = repaymentRlanMapper.selectList(queryWrapper);
        if (list.size() == 0) {
            log.info("暂无需要处理");
        } else {
            List<RepaymentPlan> planStatusList = new LinkedList<>();
            List<RepaymentRecord> repaymentRecordList = new LinkedList<>();
            for (RepaymentPlan plan : list) {
                //设定逾期的数据
                long time = plan.getBillTime().getTime() + plan.getRepayTime().getTime();
                if (time % (20 - plan.getTerm()) == plan.getTerm()) {
                    log.info("模拟为坏账记录={}", JSON.toJSONString(plan));
                    continue;
                }

                //配置还款记录
                RepaymentRecord record = loanInfoService.getRepaymentRecordByPlan(plan);
                Date payTime = record.getPayTime();
                repaymentRecordList.add(record);

                //配置还款计划的状态
                {
                    RepaymentPlan planStatus = new RepaymentPlan();
                    planStatus.setId(plan.getId());
                    planStatus.setPayTime(payTime);
                    planStatus.setRepayStatus(RepayPlanEnum.PAY.value);
                    Integer overdueDay = DateUtil.differDay(payTime, plan.getOverdueTime());
                    planStatus.setOverdueDay(overdueDay);
                    planStatus.setOverdueStatus(overdueDay > 0 ? OverdueStatusEnum.OVERDUE.value : OverdueStatusEnum.UN_OVERDUE.value);
                    planStatusList.add(planStatus);
                }

                //结清时补充的记录
                if (record.getStatus() == RepayStatusEnum.PAY_All.value
                        || record.getStatus() == RepayStatusEnum.PAY_All.value) {
                    //赛选出剩余记录
                    LambdaQueryWrapper<RepaymentPlan> queryWrapper1 = new LambdaQueryWrapper<>();
                    queryWrapper1.eq(RepaymentPlan::getDueBillNo, plan.getDueBillNo());
                    queryWrapper1.gt(RepaymentPlan::getTerm, plan.getTerm());
                    queryWrapper1.orderByAsc(RepaymentPlan::getTerm);
                    List<RepaymentPlan> remPlans = repaymentRlanMapper.selectList(queryWrapper1);
                    for (RepaymentPlan remPlan : remPlans) {
                        RepaymentPlan remPlanStatus = new RepaymentPlan();
                        remPlanStatus.setId(remPlan.getId());
                        remPlanStatus.setPayTime(payTime);
                        remPlanStatus.setRepayStatus(RepayPlanEnum.PAY.value);
                        Integer remOverdueDay = DateUtil.differDay(payTime, remPlan.getOverdueTime());
                        remPlanStatus.setOverdueDay(remOverdueDay);
                        remPlanStatus.setOverdueStatus(remOverdueDay > 0 ? OverdueStatusEnum.OVERDUE.value : OverdueStatusEnum.UN_OVERDUE.value);
                        planStatusList.add(remPlanStatus);
                    }
                }
            }

            //还款记录
            if (repaymentRecordList.size() > 0) {
                iRepaymentRecordService.saveBatch(repaymentRecordList);
                log.info("还款记录-生产成功");
            }

            //还款计划状态更新
            if (planStatusList.size() > 0) {
                this.updateBatchById(planStatusList);
                log.info("更新还款计划状态-生产成功");
            }
        }
        return re;
    }

    //queryWrapper.gt（）——大于
    //queryWrapper.le（）——小于等于
    // 计算并更新逾期状态
    @Override
    public int callOverdueStatus(Long id) {
        int reCount = 0;
        Long lastId = id;
        Date now = new Date();
        List<RepaymentPlan> list = null;
        do {
            LambdaQueryWrapper<RepaymentPlan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RepaymentPlan::getRepayStatus, RepayPlanEnum.UN_PAY);//未还款
            queryWrapper.lt(RepaymentPlan::getOverdueTime, now);///已经逾期了
            queryWrapper.last("limit 1000");
            queryWrapper.orderByDesc(RepaymentPlan::getId);
            if (lastId != null) {
                queryWrapper.lt(RepaymentPlan::getId, lastId);
            }
            list = repaymentRlanMapper.selectList(queryWrapper);
            if (!CollectionUtils.isEmpty(list)) {
                for (RepaymentPlan plan : list) {
                    lastId = plan.getId();
                    try {
                        RepaymentPlan tmpRecord = new RepaymentPlan();
                        tmpRecord.setId(plan.getId());
                        tmpRecord.setOverdueStatus(1);

                        //计算逾期天数
                        Integer day = DateUtil.differDay(now, plan.getOverdueTime());
                        tmpRecord.setOverdueDay(day);

                        //计算逾期罚息
                        if (day > 0) {
                            double monthAmount = plan.getRepayInterest() + plan.getRepayPrincipal();
                            Double[] doubles = RateUtil.listEqualPrincipalInterest(monthAmount, plan.getOverdueRate() / 365, day).get(1);
                            tmpRecord.setOverdueInterest(doubles[0]);
                        }

                        repaymentRlanMapper.updateById(tmpRecord);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } while (!CollectionUtils.isEmpty(list));
        return reCount;
    }

    @Override
    public Page<RepaymentPlan> pageList(RepaymentPlanPageReq req) {
        PageHelper.startPage(req.getPageNum(), req.getPageSize());
        LambdaQueryWrapper<RepaymentPlan> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(req.getName())) {
            queryWrapper.like(RepaymentPlan::getName, req.getName());
        }
        if (StringUtils.isNotBlank(req.getName())) {
            queryWrapper.like(RepaymentPlan::getName, req.getName());
        }
        if (StringUtils.isNotBlank(req.getSessionId())) {
            queryWrapper.like(RepaymentPlan::getSessionId, req.getSessionId());
        }
        if (StringUtils.isNotBlank(req.getUserId())) {
            queryWrapper.like(RepaymentPlan::getUserId, req.getUserId());
        }

        queryWrapper.orderByDesc(RepaymentPlan::getId);
        List<RepaymentPlan> list = repaymentRlanMapper.selectList(queryWrapper);
        return new Page<>(list, new PageInfo<>(list).getTotal(), req);
    }
}
